package SellerAgent;

import Ontologies.*;
import jade.content.lang.Codec;
import jade.content.onto.OntologyException;
import jade.content.onto.basic.Result;
import jade.core.Agent;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;

import java.util.List;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * User: jiakai
 * Date: 13-5-14
 * Time: 10:04
 * the behaviour to perform purchase request
 */
public class PerformPurchaseBehaviour extends OneShotBehaviour {
    /**
     * the message received
     */
    ACLMessage msg;
    /**
     * the purchase action which extract from message
     */
    PurchaseAction action;

    /**
     * the reference of seller's selling list
     */
    List<TreeWithPrice> sellingList;

    /**
     * the reference of in processing tree set, used for concurrency purpose
     */
    Set<String> inProcessingTrees;

    /**
     * the constructor for  PerformPurchaseBehaviour
     *
     * @param a The agent this behaviour belongs to.
     * @param msg the message received
     * @param action the purchase action which extract from message
     * @param sellingList the reference of seller's selling list
     * @param inProcessingTrees the reference of in processing tree set, used for concurrency purpose
     */
    public PerformPurchaseBehaviour(Agent a, ACLMessage msg, PurchaseAction action, List<TreeWithPrice> sellingList,Set<String> inProcessingTrees) {
        super(a);
        this.msg = msg;
        this.action = action;
        this.sellingList = sellingList;
        this.inProcessingTrees=inProcessingTrees;
    }

    /**
     *  this method take the responsibility of performing purchase request
     *
     * @param msg  the message received
     * @param action   the purchase action which extract from message
     * @throws Codec.CodecException
     * @throws OntologyException
     */
    private void performPurchaseRequest(ACLMessage msg,PurchaseAction action) throws Codec.CodecException, OntologyException {
        boolean found=false;// the flag whether found target tree or not
        PurchaseResponse response=new PurchaseResponse();

        System.out.println("performPurchaseRequest");

        //initial target tree
        TreeWithPrice targetTree=new TreeWithPrice();
        targetTree.setCommonName(action.getCommonName());
        targetTree.setLatinName(action.getLatinName());
        targetTree.setQuantity(action.getQuantity());

        //initial response
        response.setCommonName(targetTree.getCommonName());
        response.setLatinName(targetTree.getLatinName());

        for (TreeWithPrice tree : sellingList) {
            if (FruitTreeNurserySystemOntology.isSameTreeType(targetTree, tree)) {
                found=true;


                if (targetTree.getQuantity() >= tree.getQuantity()) {
                    // if have insufficient quantity
                    response.setQuantity(tree.getQuantity());
                    targetTree.setQuantity(tree.getQuantity());
                    tree.setQuantity(0);//sold all available amount
                    sellingList.remove(tree);  //remove this tree from selling list
                }
                else
                {
                    // if have enough quantity
                    response.setQuantity(targetTree.getQuantity());

                    tree.setQuantity(tree.getQuantity()-targetTree.getQuantity());
                }

                targetTree.setUnitPrice(tree.getUnitPrice());
                response.setUnitPrice(tree.getUnitPrice());
                response.setErrorCode(0); // set the response status as no error

                //create a new transaction & update corresponding gui
                ((Seller)myAgent).CreateNewTransactionRecord(targetTree,msg);
                break;
            }
        }

        if(!found)
        {
            // if cannot find target tree, set response as sold out
            response.setErrorCode(1);
        }

        //if(result!=null)
        {   //send response back to buyer
            Result result = new Result(action, response);
            ACLMessage reply = msg.createReply();
            reply.setPerformative(ACLMessage.INFORM);
            myAgent.getContentManager().fillContent(reply, result);
            myAgent.send(reply);
            System.out.println("performPurchaseRequest  send response");
        }
    }

    @Override
    public void action() {
        try {
            performPurchaseRequest(msg,action);
        } catch (Codec.CodecException e) {
            e.printStackTrace();
        } catch (OntologyException e) {
            e.printStackTrace();
        }
        finally
        {
            //remove the tree from in processing set, then the other request for this type of tree can be performed
            inProcessingTrees.remove(action.getCommonName());
        }
    }
}
